home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 8 / FM Towns Free Software Collection 8.iso / t_os / artemis / artsrc2 / tiff.c < prev    next >
C/C++ Source or Header  |  1994-06-01  |  8KB  |  303 lines

  1. /*
  2.     tiff.c
  3.  
  4.     TIFF画像セーブ・ロード関数
  5.     (200KB程度のメモリが必要)
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <malloc.h>
  10. #include <egb.h>
  11. #include <msdos.cf>
  12.  
  13. #include <ryosuke.h>
  14.  
  15. #include <tifflib.h>
  16. #include <msdos.cf>
  17. #include <usrlib.h>
  18.  
  19. #define    DATABUF        (32*1024)
  20. #define    IMAGEBUF    (16*1024)
  21. #define    WORKBUF        _max(DECOMP_WORK_SIZE,COMP_WORK_SIZE)
  22.  
  23. static char *databuf = NULL;
  24. static char *imagebuf = NULL;
  25. static char *workbuf = NULL;
  26. static int x,y;
  27. static FILE *fp;
  28. static    TIFFinfo    tiffinfo;
  29.  
  30.  
  31. /*--------------------------------------------------------*/
  32. /*                   作業用メモリの確保                   */
  33. /*--------------------------------------------------------*/
  34.  
  35.  
  36. int TIFFinitwork()
  37. // 返値 0=正常終了  -1=メモリ不足
  38. {
  39.     if (databuf == NULL) {        // 作業用メモリ領域の確保
  40.         if ((databuf = malloc(DATABUF+IMAGEBUF+WORKBUF)) == NULL)
  41.             return -1;
  42.         imagebuf = databuf + DATABUF;
  43.         workbuf = imagebuf + IMAGEBUF;
  44.     }
  45.     return 0;
  46. }
  47.  
  48.  
  49. /*--------------------------------------------------------*/
  50. /*                 TIFF データの読み出し                  */
  51. /*--------------------------------------------------------*/
  52.  
  53.  
  54. static int load_x0, load_y0;
  55.  
  56.  
  57. static int input_data(char *buf, int size)
  58. {
  59.     fread(buf,1,size,fp);
  60.     return 0;
  61. }
  62.  
  63.  
  64. static int output_image(char *buf, int lofs, int lines)
  65. {
  66.     struct { char *buf;  short sel, sx,sy,ex,ey; } p;
  67.     p.buf = buf;            p.sel = getds();
  68.     p.sx = load_x0;            p.ex = load_x0 + x - 1;
  69.     p.sy = load_y0 + lofs;    p.ey = load_y0 + lofs + lines - 1;
  70.     EGB_putBlock( EGB_work, 0, (char*)&p );
  71.     return 0;
  72.     /*
  73.         if (!(_wrtpage & 0x80)) {
  74.             struct { char *buf;  short sel, sx,sy,ex,ey; } p;
  75.             p.buf = buf;            p.sel = getds();
  76.             p.sx = load_x0;            p.ex = load_x0 + x - 1;
  77.             p.sy = load_y0 + lofs;    p.ey = load_y0 + lofs + lines - 1;
  78.             EGB_putBlock(EGB_work, 0, (char*)&p);
  79.             return 0;
  80.         } else {
  81.             gputblk(buf, load_x0, load_y0+lofs, x, lines, 0);
  82.             return 0;
  83.         }
  84.     */
  85. }
  86.  
  87.  
  88. static int (*putimagefunc)() = NOFNCint;
  89.  
  90.  
  91. void TIFFload_putimagefunc(int (*func)())
  92. {
  93.     putimagefunc = func;
  94. }
  95.  
  96.  
  97. int TIFFload(char *fname, int x0, int y0)
  98. // 返値  0=成功  -1=失敗
  99. {
  100.     if (TIFFinitwork() != 0)
  101.         return -1;
  102.     load_x0 = x0;
  103.     load_y0 = y0;
  104.     if ((fp = fopen(fname,"rb")) == NULL)
  105.         return -1;
  106.     fread(databuf,1,DATABUF,fp);        // ヘッダの読み出し
  107.     if (TIFF_getHead(databuf,DATABUF) < 0)
  108.         goto END;
  109.     int pixelsize;
  110.     int comp,fill;
  111.     long strip,clut;
  112.     if ((pixelsize = TIFF_checkMode(&x,&y,&comp,&fill,&strip,&clut)) < 0)
  113.         goto END;
  114.     if (pixelsize == 24)
  115.         goto END;
  116.     if (putimagefunc == NOFNCint)
  117.         TIFF_setLoadFunc(output_image, input_data);
  118.     else
  119.         TIFF_setLoadFunc(putimagefunc, input_data);
  120.     int img_xlen, img_ylen;
  121.     img_xlen = (pixelsize==4 ? ((x+7) & 0xfffffff8) : x);
  122.     img_ylen = IMAGEBUF / ((img_xlen*pixelsize+7)/8);
  123.     if (clut!=0) {
  124.         char plt[256*8+4];
  125.         TIFF_getPal(plt);
  126.         EGB_palette(EGB_work, 0, plt);
  127.     }
  128.     TIFF_loadImage(pixelsize,x,y,strip,fill,comp,
  129.                    imagebuf,img_xlen,img_ylen,workbuf);
  130. END:
  131.     fclose(fp);
  132.     // TIFF情報構造体の更新
  133.     {
  134.         tiffinfo.xlen = x;
  135.         tiffinfo.ylen = y;
  136.     }
  137.     return 0;
  138. }
  139.  
  140.  
  141. /*--------------------------------------------------------*/
  142. /*                 TIFF データの書き込み                  */
  143. /*--------------------------------------------------------*/
  144.  
  145.  
  146. static int save_x1, save_y1, save_xlen, save_ylen;
  147.  
  148.  
  149. static int output_data(char *buf, long size)
  150. {
  151.     if (fwrite(buf,1,size,fp) < size)
  152.         return -1;
  153.     return 0;
  154. }
  155.  
  156.  
  157. static int input_image(char *buf,int lofs,int lines)
  158. {
  159.     struct { char *buf;  short sel, sx,sy,ex,ey; } p;
  160.     p.buf = buf;    p.sel = getds();
  161.     p.sx = save_x1;            p.ex = save_x1 + save_xlen - 1;
  162.     p.sy = save_y1 + lofs;    p.ey = save_y1 + lofs + lines - 1;
  163.     EGB_getBlock(EGB_work, (char*)&p);
  164.     return 0;
  165. }
  166.  
  167.  
  168. #define    NOFNC    ((int (*)())0)
  169.  
  170.  
  171. static int (*getimagefunc)() = NOFNCint;
  172.  
  173.  
  174. void TIFFsave_getimagefunc(int (*func)())
  175. {
  176.     getimagefunc = func;
  177. }
  178.  
  179.  
  180. int TIFFsave(char *fname, int x1,int y1,int xlen,int ylen, bool compress)
  181. // 返値  0=成功  -1=画面モード/ファイル名の間違い
  182. //                 -2=メモリ不足  -3=ディスク領域不足  -4=get関数エラー
  183. {
  184.     if (TIFFinitwork() != 0)
  185.         return -2;
  186.     save_x1 = x1;
  187.     save_y1 = y1;
  188.     save_xlen = xlen;
  189.     save_ylen = ylen;
  190.     int pixelsize,headsize;
  191.     char _palet[256*8+4],*palet;
  192.     palet = NULL;
  193.     headsize = 512;
  194.  
  195.     int scrmod, wrtpage;
  196.     wrtpage = EGB_getWritePage(_egbwork, getds());
  197.     if ( wrtpage == 0 )
  198.         scrmod = ( EGB_getResolution( NULL, NULL ) & 255 );
  199.     else
  200.         scrmod = ( (EGB_getResolution( NULL, NULL ) >> 8) & 255 );
  201.  
  202.     if (scrmod == 3 || scrmod == 4)
  203.     {
  204.         pixelsize = 4,  x = 640, y = 480;
  205.         EGB_getPalette(wrtpage, _palet);
  206.         palet = _palet;
  207.     }
  208.     else if (5 <= scrmod && scrmod <= 8)
  209.         pixelsize = 16,    x = 256, y = 240;
  210.     else if (9 <= scrmod && scrmod <= 11)
  211.         pixelsize = 16, x = 320, y = 240;
  212.     else if (12 <= scrmod && scrmod <= 14)
  213.     {
  214.         pixelsize = 8,  x = 640, y = 480;
  215.         EGB_getPalette(wrtpage, _palet);
  216.         palet = _palet;
  217.         headsize = 2048;
  218.     }
  219.     else if (15 <= scrmod && scrmod <=18)
  220.         pixelsize = 16,  x = 512, y = 480;
  221.     else
  222.         return -1;
  223.     //
  224.     // (1) ファイルをオープンし、ヘッダのサイズ分シークする。
  225.     //     ヘッダサイズ : 256色モード=2048 bytes  その他モード=512 bytes
  226.     if ((fp = fopen(fname,"wb")) == NULL)
  227.         return -1;
  228.     if (fwrite(databuf,1,headsize,fp) < headsize)
  229.         { fclose(fp);  return -3; }
  230.     //
  231.     // (2) 画面データの取り出しルーチンと、ファイルへ書き出すルーチンを登録
  232.     if (getimagefunc == NOFNCint)
  233.         TIFF_setSaveFunc(output_data,input_image);
  234.     else
  235.         TIFF_setSaveFunc(output_data,getimagefunc);
  236.     //
  237.     // (3) TIFF のセーブルーチンをコールする
  238.     int img_xlen,img_ylen;
  239.     img_xlen = (pixelsize==4 ? ((save_xlen+7) & 0xfffffff8) : save_xlen);
  240.     img_ylen = IMAGEBUF / ((img_xlen*pixelsize+7)/8);
  241.     int cmp_size;
  242.     cmp_size = TIFF_saveImage(pixelsize, save_xlen, save_ylen, (compress? 5:1),
  243.                               databuf, DATABUF, imagebuf, img_xlen, img_ylen,
  244.                               workbuf);
  245.     if (cmp_size == -1)
  246.         { fclose(fp);  return -4; }
  247.     else if (cmp_size == -2)
  248.         { fclose(fp);  return -3; }
  249.     //
  250.     // (4) ヘッダ情報をつくる
  251.     TIFF_setHead(databuf,pixelsize,save_xlen,save_ylen,
  252.                  (compress? cmp_size: 0), palet);
  253.     //
  254.     // (5) ファイルを先頭にシークして、ヘッダを書き出し、クローズ
  255.     fflush(fp);
  256.     long nowfp;
  257.     nowfp = ftell(fp);
  258.     rewind(fp);
  259.     if (fwrite(databuf,1,headsize,fp) < headsize)
  260.         { fclose(fp);  return -3; }
  261.     fflush(fp);
  262.     fseek(fp,nowfp,SEEK_SET);
  263.     fclose(fp);
  264.     // TIFF情報構造体の更新
  265.     {
  266.         tiffinfo.xlen = save_xlen;
  267.         tiffinfo.ylen = save_ylen;
  268.     }
  269.     return 0;
  270. }
  271.  
  272.  
  273. /*--------------------------------------------------------*/
  274. /*         TIFF データファイルに関する情報を得る          */
  275. /*--------------------------------------------------------*/
  276.  
  277.  
  278. int TIFFgetinfo(char *fname, TIFFinfo *info)
  279. // 返値  0=正常終了
  280. //      -1=ファイルが存在しない
  281. //      -2=TIFF形式ではない
  282. //      -3=メモリが足りない
  283. {
  284.     if (TIFFinitwork() != 0)
  285.         return -3;
  286.     if ((fp = fopen(fname,"rb")) == NULL)
  287.         return -1;
  288.     fread(databuf,1,DATABUF,fp);        // ヘッダの読み出し
  289.     fclose(fp);
  290.     if (TIFF_getHead(databuf,DATABUF) < 0)
  291.         return -2;
  292.     int xlen,ylen,pixelsize,comp,fill;  long strip,clut;
  293.     if ((pixelsize = TIFF_checkMode(&xlen,&ylen,&comp,&fill,&strip,&clut)) < 0)
  294.         return -2;
  295.     info->xlen = xlen;
  296.     info->ylen = ylen;
  297.     info->compress = (comp == 1 ? NO : YES);
  298.     info->pixelsize = pixelsize;
  299.     return 0;
  300. }
  301.  
  302. /* end of tiff.c */
  303.